package com.fin.quant.rpc.bean.server;

import com.fin.quant.common.AtomUtils;
import com.orbitz.consul.AgentClient;
import com.orbitz.consul.Consul;
import com.orbitz.consul.model.agent.ImmutableRegistration;
import com.orbitz.consul.model.agent.Registration;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.BindableService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Map;
import java.util.concurrent.Executors;

@Component
@Slf4j
public class GrpcServerBean {

    private Server server;

    private final ApplicationContext applicationContext;

    @Autowired
    private Consul consul;

    @Value("${spring.grpc.server.host:}")
    private String server_host;
    @Value("${spring.grpc.server.port:0}")
    private int server_port;

    public GrpcServerBean(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @PostConstruct
    public void start() throws Exception {
        log.info("GrpcServerBean.server_host={} server_port={}", server_host, server_port);

        // 从 Spring 上下文扫描所有 @GrpcService 的 Bean
        Map<String, Object> grpcServices = applicationContext.getBeansWithAnnotation(GrpcService.class);

        if (MapUtils.isEmpty(grpcServices)) {
            //没有实现，那么不要初始化线程池资源，避免浪费
            return;
        }

        ServerBuilder<?> serverBuilder = ServerBuilder.forPort(server_port)
                .executor(Executors.newFixedThreadPool(200));

        for (Object serviceBean : grpcServices.values()) {
            if (serviceBean instanceof BindableService) {
                serverBuilder.addService((BindableService) serviceBean);

                AgentClient agentClient = consul.agentClient();

                GrpcService annotation = AnnotationUtils.findAnnotation(serviceBean.getClass(), GrpcService.class);

                String serviceName = annotation.value();

                // 健康检查 (HTTP 或 TCP 都可以)
                Registration.RegCheck check = Registration.RegCheck.tcp(server_host + ":" + server_port, 10);


                AtomUtils.getId();
                Registration service = ImmutableRegistration.builder()
                        .id(serviceName + "-" + server_port) // 服务唯一 ID
                        .name(serviceName)                   // 服务名（客户端发现时用）
                        .address(server_host)                // 服务地址
                        .port(server_port)                   // 服务端口
                        .check(check)                        // 健康检查
                        .build();

                agentClient.register(service);

                log.info("🚀 gRPC consul registered " + serviceName);
            } else {
                throw new IllegalArgumentException("GrpcService 必须继承 BindableService: " + serviceBean.getClass());
            }
        }

        server = serverBuilder.build().start();
        log.info("🚀 gRPC Server started, listening on port " + server_port);


    }

    @PreDestroy
    public void stop() throws Exception {
        if (server != null) {
            server.shutdown();
            log.info("🛑 gRPC Server stopped");
        }

        AgentClient agentClient = consul.agentClient();
//        agentClient.deregister(serviceId);
    }
}
